以前只是知道浏览器会缓存静态文件,在不需要缓存时ctrl+F5刷新,为了方便用户可能还会在资源的路径后面添加一个版本号;直到现在我决定再把问题深入一点。主要有几个问题:浏览器为什么会缓存?浏览器是怎么缓存的?会缓存多久?扩展到前端性能优化该怎么做?以下是我对这几个问题的简单理解。

# 浏览器为什么会缓存?

当我们打开一个网页的时候,浏览器首先会通过链接(域名)获取到服务器上的一个html文件,然后浏览器再通过这个html去获取一些css,js,img等静态资源。但是如果每次访问这个页面浏览器都要去服务器下载一遍,是不是明显不太合理,浪费宽度,浪费时间,浪费服务器资源。所以最好的方式就是浏览器将这些文件储存在本地,第二次访问的时候就可以直接从本地获取。

# 浏览器是怎么缓存的?

Cache-Control 通用消息头字段,被用于在http请求和响应中,通过指定指令来实现缓存机制。 首先说明一下,这个属性不是在前端代码里设置的,而是在服务器上;我们可以在本地安装个nginx做一些简单的验证。 常用参数有如下几个:

  • private(默认值):

表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。私有缓存可以缓存响应内容,比如:对应用户的本地浏览器。

这个是Cache-Control的默认值,当你在NetWork中没有看见相关响应头时实际就是这个。他的策略就是会在浏览器中缓存静态资源,具体缓存的时间与Last-modified有关,浏览器有自己的算法,不同浏览器得出的时间也不一样的。大致的规律就是文件经常修改,则缓存的时间越短。相对于默认值我觉得这是比较合理的。

  • public

表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存,即使是通常不可缓存的内容。(例如:1.该响应没有max-age指令或Expires消息头;2. 该响应对应的请求方法是 POST 。)

  • no-store

缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。

当设置为no-store之后,浏览器不会做任何缓存,每次打开页面浏览器都会到服务器下载资源,这应该是最不常用的一种了。

  • no-cache

在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)。

协商缓存还和另外两个响应头有关系:Last-Modified(文件最后修改时间)和ETag(和文件数据相关的随机字符,文件改动时它也会改变,由服务器生成)。

他的策略就是:第一次访问页面时将静态文件存储在本地,后面每次访问的时候都通过If-Modified-SinceIf-None-Match到服务器端去做验证,如果文件已经修改了则重新下载,如果文件没有修改则返回304,浏览器会从本地读取。

也就是说协商缓存虽然有缓存,但是每次都需要向服务器发送请求验证文件有没有修改。我个人认为只适用于html文件。

  • max-age=<seconds>

设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。

强缓存。这个其实就很好理解了,就是设置一个缓存时间,只要时间没到,它永远都是从内存中读取。一般用来和版本号搭配起来使用(版本号的意思就是文件改变之后必须改变文件引用路径)。

上次更新:: 5/25/2020, 5:51:54 PM